package org.japo.java.binding.samples;

import java.awt.Font;
import java.io.FileReader;
import java.io.FileWriter;
import javax.swing.JOptionPane;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.apache.commons.beanutils.BeanUtils;
import org.japo.java.entities.Rotulo;

/**
 *
 * @author José A. Pacheco Ondoño - joanpaon@gmail.com
 */
public class EstiloEnlazado extends javax.swing.JFrame {

    // Referencia al modelo
    private Rotulo rotulo;

    // Fichero de persistencia
    private final String FICHERO = "rotulo.xml";

    // Valores predeterminados para la clase Font
    private final String FAMILIA = "Serif";
    private final boolean NEGRITA = false;
    private final boolean CURSIVA = false;
    private final int TALLA = 24;

    public EstiloEnlazado() {
        iniciarAnterior();
        initComponents();
        iniciarPosterior();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        bindingGroup = new org.jdesktop.beansbinding.BindingGroup();

        pnlEstilo = new javax.swing.JPanel();
        cbxNegrita = new javax.swing.JCheckBox();
        cbxCursiva = new javax.swing.JCheckBox();
        pnlArchivo = new javax.swing.JPanel();
        btnCargar = new javax.swing.JButton();
        btnGuardar = new javax.swing.JButton();
        lblMuestra = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Estilo enlazado");
        setResizable(false);

        pnlEstilo.setBorder(javax.swing.BorderFactory.createTitledBorder("Estilo"));

        cbxNegrita.setText("Negrita");
        cbxNegrita.setMaximumSize(new java.awt.Dimension(71, 25));
        cbxNegrita.setMinimumSize(new java.awt.Dimension(71, 25));
        cbxNegrita.setPreferredSize(new java.awt.Dimension(71, 25));

        org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${rotulo.negrita}"), cbxNegrita, org.jdesktop.beansbinding.BeanProperty.create("selected"), "negrita");
        bindingGroup.addBinding(binding);

        cbxNegrita.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbxNegritaActionPerformed(evt);
            }
        });

        cbxCursiva.setText("Cursiva");

        binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, this, org.jdesktop.beansbinding.ELProperty.create("${rotulo.cursiva}"), cbxCursiva, org.jdesktop.beansbinding.BeanProperty.create("selected"), "cursiva");
        bindingGroup.addBinding(binding);

        cbxCursiva.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cbxCursivaActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout pnlEstiloLayout = new javax.swing.GroupLayout(pnlEstilo);
        pnlEstilo.setLayout(pnlEstiloLayout);
        pnlEstiloLayout.setHorizontalGroup(
            pnlEstiloLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlEstiloLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlEstiloLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(cbxNegrita, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cbxCursiva, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pnlEstiloLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {cbxCursiva, cbxNegrita});

        pnlEstiloLayout.setVerticalGroup(
            pnlEstiloLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlEstiloLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(cbxNegrita, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(cbxCursiva, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pnlArchivo.setBorder(javax.swing.BorderFactory.createTitledBorder("Archivo"));

        btnCargar.setText("Cargar");
        btnCargar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCargarActionPerformed(evt);
            }
        });

        btnGuardar.setText("Guardar");
        btnGuardar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnGuardarActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout pnlArchivoLayout = new javax.swing.GroupLayout(pnlArchivo);
        pnlArchivo.setLayout(pnlArchivoLayout);
        pnlArchivoLayout.setHorizontalGroup(
            pnlArchivoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlArchivoLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(pnlArchivoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(btnCargar, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnGuardar, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pnlArchivoLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {btnCargar, btnGuardar});

        pnlArchivoLayout.setVerticalGroup(
            pnlArchivoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(pnlArchivoLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(btnCargar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(btnGuardar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        lblMuestra.setBackground(new java.awt.Color(255, 255, 255));
        lblMuestra.setFont(new java.awt.Font("Serif", 0, 24)); // NOI18N
        lblMuestra.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        lblMuestra.setText("Texto de prueba");
        lblMuestra.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.LOWERED));
        lblMuestra.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        lblMuestra.setMaximumSize(new java.awt.Dimension(254, 104));
        lblMuestra.setMinimumSize(new java.awt.Dimension(254, 104));
        lblMuestra.setOpaque(true);
        lblMuestra.setPreferredSize(new java.awt.Dimension(254, 104));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(lblMuestra, javax.swing.GroupLayout.PREFERRED_SIZE, 254, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(pnlEstilo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(pnlArchivo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(lblMuestra, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(pnlArchivo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(pnlEstilo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        bindingGroup.bind();

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>//GEN-END:initComponents

    private void btnGuardarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGuardarActionPerformed
        try {
            exportarModelo();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Error al guardar los datos");
        }
    }//GEN-LAST:event_btnGuardarActionPerformed

    private void btnCargarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCargarActionPerformed
        try {
            importarModelo();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Error al cargar los datos");
        }
    }//GEN-LAST:event_btnCargarActionPerformed

    private void cbxNegritaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbxNegritaActionPerformed
        actualizarAspecto();
    }//GEN-LAST:event_cbxNegritaActionPerformed

    private void cbxCursivaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cbxCursivaActionPerformed
        actualizarAspecto();
    }//GEN-LAST:event_cbxCursivaActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /*
         * If Nimbus (introduced in Java SE 6) is not available, stay with the
         * default look and feel. For details see
         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(EstiloEnlazado.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(EstiloEnlazado.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(EstiloEnlazado.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(EstiloEnlazado.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new EstiloEnlazado().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnCargar;
    private javax.swing.JButton btnGuardar;
    private javax.swing.JCheckBox cbxCursiva;
    private javax.swing.JCheckBox cbxNegrita;
    private javax.swing.JLabel lblMuestra;
    private javax.swing.JPanel pnlArchivo;
    private javax.swing.JPanel pnlEstilo;
    private org.jdesktop.beansbinding.BindingGroup bindingGroup;
    // End of variables declaration//GEN-END:variables

    private void actualizarAspecto() {
        // Familia de la fuente del rotulo
        String familia = rotulo.getFamilia();

        // Estilo de la fuente del rotulo
        int negrita = rotulo.isNegrita() ? Font.BOLD : Font.PLAIN;
        int cursiva = rotulo.isCursiva() ? Font.ITALIC : Font.PLAIN;
        int estilo = negrita + cursiva;

        // Talla de la fuente del rotulo
        int talla = rotulo.getTalla();

        // Fuente del rotulo
        lblMuestra.setFont(new Font(familia, estilo, talla));
    }

    public Rotulo getRotulo() {
        return rotulo;
    }

    public void setRotulo(Rotulo rotulo) {
        this.rotulo = rotulo;
    }

    private void iniciarPosterior() {
        actualizarAspecto();
    }

    private void exportarModelo() throws Exception {
        // Referencia al cauce de fichero
        FileWriter fw = null;

        try {
            // Crea el cauce de salida
            fw = new FileWriter(FICHERO);

            // Establece el contexto XML - Clase Transferencia
            JAXBContext context = JAXBContext.newInstance(Rotulo.class);

            // Crea el escritor de XML para el contexto actual
            Marshaller m = context.createMarshaller();

            // Formato salida de XML - HUMANO
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            // Exporta la clase al fichero
            m.marshal(rotulo, fw);

            // Mensaje de adevertencia
            JOptionPane.showMessageDialog(this, "Datos guardados correctamente.");
        } finally {
            if (fw != null) {
                // Cierra el cauce al fichero
                fw.close();
            }
        }
    }

    private void importarModelo() throws Exception {
        // Referencia al cauce de fichero
        FileReader fr = null;

        try {
            // Crea el cauce de salida
            fr = new FileReader(FICHERO);

            // Establece el contexto XML - Clase Transferencia
            JAXBContext context = JAXBContext.newInstance(Rotulo.class);

            // Crea el lector de XML para el contexto actual
            Unmarshaller u = context.createUnmarshaller();

            // Crea una clase con los datos importados del fichero
            Rotulo rotuloImp = (Rotulo) u.unmarshal(fr);

            // Vuelca los datos a la entidad
            BeanUtils.copyProperties(rotulo, rotuloImp);

            // Actualiza el rotulo
            actualizarAspecto();
        } finally {
            if (fr != null) {
                fr.close();
            }
        }
    }

    private void iniciarAnterior() {
        rotulo = new Rotulo(FAMILIA, NEGRITA, CURSIVA, TALLA);
    }
}
